package com.shuai.orderfood.merchants.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shuai.orderfood.common.Constant;
import com.shuai.orderfood.common.HttpStatusCodeEnum;
import com.shuai.orderfood.common.JwtUtil;
import com.shuai.orderfood.exceptions.OrderFoodException;
import com.shuai.orderfood.merchants.mapper.MerchantsRoleMapper;
import com.shuai.orderfood.merchants.mapper.MerchantsUserMapper;
import com.shuai.orderfood.merchants.pojo.MerchantsRole;
import com.shuai.orderfood.merchants.pojo.MerchantsUser;
import com.shuai.orderfood.merchants.dto.LoginDto;
import com.shuai.orderfood.merchants.vo.LoginVo;
import com.shuai.orderfood.merchants.dto.RegisterDto;
import com.shuai.orderfood.merchants.service.AuthService;
import jakarta.annotation.Resource;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 认证服务类
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Resource
    private MerchantsUserMapper merchantsUserMapper;
    @Resource
    private MerchantsRoleMapper merchantsRoleMapper;
    @Resource
    private PasswordEncoder passwordEncoder;

    /**
     * 用户注册
     */
    @Override
    @Transactional
    public void register(RegisterDto request) throws Exception {
        String username = request.getUsername();
        String password = request.getPassword();
        String phone = request.getPhone();
        Integer roleId = request.getRoleId();
        if(!StringUtils.hasLength(username)) {
            throw new OrderFoodException(HttpStatusCodeEnum.USERNAMENOTEXIST.getCode(),HttpStatusCodeEnum.USERNAMENOTEXIST.getMessage());
        }else if(!StringUtils.hasLength(password)) {
            throw new OrderFoodException(HttpStatusCodeEnum.PASSWORDNOTNULL.getCode(),HttpStatusCodeEnum.PASSWORDNOTNULL.getMessage());
        }else if(!StringUtils.hasLength(phone)) {
            throw new OrderFoodException(HttpStatusCodeEnum.PHONENOTNULL.getCode(),HttpStatusCodeEnum.PHONENOTNULL.getMessage());
        }else if(roleId == null) {
            throw new OrderFoodException(HttpStatusCodeEnum.ROLENOTNULL.getCode(),HttpStatusCodeEnum.ROLENOTNULL.getMessage());
        }

        // 检查用户名是否已存在
        LambdaQueryWrapper<MerchantsUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MerchantsUser::getUsername, username);
        Long usernameCount = merchantsUserMapper.selectCount(lambdaQueryWrapper);
        if (usernameCount > 0) {
            throw new OrderFoodException(HttpStatusCodeEnum.USERNAMEEXIST.getCode(), HttpStatusCodeEnum.USERNAMEEXIST.getMessage());
        }

        //校验手机号是否合法
        boolean isLegal = Constant.PHONE_PATTERN.matcher(request.getPhone()).matches();
        if (!isLegal) {  //手机号不合法
            throw new OrderFoodException(HttpStatusCodeEnum.PHONELIIEGAL.getCode(), HttpStatusCodeEnum.PHONELIIEGAL.getMessage());
        }

        // 检查手机号是否已存在
        lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MerchantsUser::getPhone, request.getPhone());
        Long phoneCount = merchantsUserMapper.selectCount(lambdaQueryWrapper);
        if (phoneCount > 0) {
            throw new OrderFoodException(HttpStatusCodeEnum.PHONEEXIST.getCode(), HttpStatusCodeEnum.PHONEEXIST.getMessage());
        }

        // 检查角色是否存在
        MerchantsRole role = merchantsRoleMapper.selectById(request.getRoleId());
        if (role == null) {
            throw new OrderFoodException(HttpStatusCodeEnum.ROLENOTEXIST.getCode(), HttpStatusCodeEnum.ROLENOTEXIST.getMessage());
        }

        // 如果要注册超级管理员，检查是否已存在
        if (request.getRoleId() == 1) {
            lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(MerchantsUser::getIsSuper, Constant.IS_SUPER_YES);
            List<MerchantsUser> merchantsUserList = merchantsUserMapper.selectList(lambdaQueryWrapper);
            if (!CollectionUtils.isEmpty(merchantsUserList)) {
                throw new OrderFoodException(HttpStatusCodeEnum.SUPERADMINEXIST.getCode(), HttpStatusCodeEnum.SUPERADMINEXIST.getMessage());
            }
        }

        // 创建新用户
        MerchantsUser user = new MerchantsUser();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setPhone(request.getPhone());
        user.setRoleId(request.getRoleId());

        merchantsUserMapper.insert(user);
    }

    /**
     * 用户登录
     */
    @Override
    public LoginVo login(LoginDto request) throws Exception {
        // 查找用户（包含角色信息）
        LambdaQueryWrapper<MerchantsUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MerchantsUser::getUsername, request.getUsername());
        MerchantsUser user = merchantsUserMapper.selectOne(lambdaQueryWrapper);
        if (user == null) {
            throw new OrderFoodException(HttpStatusCodeEnum.USERNAMENOTEXIST.getCode(), HttpStatusCodeEnum.USERNAMENOTEXIST.getMessage());
        }

        // 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new OrderFoodException(HttpStatusCodeEnum.PASSWORDWRONG.getCode(), HttpStatusCodeEnum.PASSWORDWRONG.getMessage());
        }

        // 生成JWT token
        String token = JwtUtil.generateToken(user.getUserId(), user.getUsername());

        // 组织返回数据
        LambdaQueryWrapper<MerchantsRole> roleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roleLambdaQueryWrapper.eq(MerchantsRole::getRoleId, user.getRoleId());
        MerchantsRole merchantsRole = merchantsRoleMapper.selectOne(roleLambdaQueryWrapper);
        LoginVo loginResponse = new LoginVo();
        loginResponse.setUserId(user.getUserId());
        loginResponse.setUsername(user.getUsername());
        loginResponse.setRoleId(user.getRoleId());
        loginResponse.setRoleName(merchantsRole.getRoleName());
        loginResponse.setToken(token);
        loginResponse.setPhone(user.getPhone());
        loginResponse.setIsSuper(user.getIsSuper());
        return loginResponse;
    }
}
